﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace X3DLib
{
    public class X3DString 
    {
        static int max_deep = 100;
        static string[] headcode = new string[6];
        static string background = "<Background />";
        static string endx3d = "</Scene>\n</X3D>\n";
        static string[] group = new string[max_deep];

        public static string getX3dHead()
        {
            string basehead = "";
            headcode[0] = "<?xml version='1.0' encoding='UTF-8'?>\n";
            headcode[1] = "<!DOCTYPE X3D PUBLIC 'ISO//Web3D//DTD X3D 3.0//EN' 'http://www.web3d.org/specifications/x3d-3.0.dtd'>\n";
            headcode[2] = "<X3D profile='Immersive' version='3.0'>\n";
            headcode[3] = "<head>\n<META HTTP-EQUIV=\"pragma\" CONTENT=\"no-cache\" /><META HTTP-EQUIV=\"Cache-Control\" CONTENT=\"no-cache, must-revalidate\" /><META HTTP-EQUIV=\"expires\" CONTENT=\"Wed, 26 Feb 1997 08:21:57 GMT\" />";
            headcode[4] = "</head>\n";
            headcode[5] = "<Scene>\n";

            for (int i = 0; i < 6; i++)
            {
                basehead = basehead + headcode[i];
            }
            return basehead;
        }
        public static string getX3dBackground(string skycolor)
        {
            background = "<Background skyColor=" + "'" + skycolor +"'/>\n";
            return background;
        }
        public static string getX3dEnd()
        {
            //return "</X3D>\n";
            return "</Scene>\n</X3D>\n"; 
        }
        public static string getX3dApperance()
        {
            return "</X3D>\n";
        }

        public static string getX3dAll(object x3dbody)
        {
            return getX3dHead() + toString(x3dbody) + getX3dEnd();//"</Scene>\n</X3D>\n"; //endx3d;
        }

        public static string getX3dAll(string skycolor,object x3dbody)
        {
            return getX3dHead() + getX3dBackground(skycolor)+ toString(x3dbody) + getX3dEnd();//"</Scene>\n</X3D>\n"; //endx3d;
        }
        public static string toString(object b)
        {
            //所有object类型的对象属性被视为子节点，而string类型的对象属性被视为属性
            Type t = b.GetType();
            string typeName = t.Name;

            if (t == typeof(List<Object>))
            {
                string temp = "";
                //子节点
                foreach (Object ob in ((List<Object>)b))
                {
                    //temp +=((List <string >)b)[i]+"#";
                    if (ob.GetType() == typeof(string))
                    {
                        temp += ob.ToString();
                    }
                    else
                    {
                        temp += toString(ob);

                    }
                }
                return temp;
            }
            else
            {
                string strP = "";
                //判断是否为构造组节点
                if (typeName != "Tree" && typeName != "Fire" && typeName != "Grass"&&typeName !="Water")
                {
                    if (typeName.Equals("_Cone"))
                    {
                        typeName = "Cone";
                    }
                    strP = "<" + typeName;
                }
                string strC = "";
                //属性历遍
                foreach (PropertyInfo pi in t.GetProperties())
                {
                    try
                    {
                        object o = pi.GetValue(b, null);
                        if (o != null)
                        {
                            //if (pi.PropertyType == typeof(Tree)) continue;
                            if (pi.PropertyType == typeof(string))      //属于字符串类型，故非复杂类
                            {

                                if (o.ToString().Length != 0)
                                {
                                    strP += " " + pi.Name + "=\"";
                                    strP += o.ToString() + "\"";
                                }
                            }
                            else    //如果是某非字符串类则递归调用
                            {
                                strC += toString(o);
                            }
                        }
                    }
                    catch (Exception )
                    {
                    }


                }
                //判断是否为构造组节点
                if (typeName != "Tree" && typeName != "Fire" && typeName != "Grass" && typeName != "Water")
                {
                    if (typeName.Equals("_Cone"))
                    {
                        typeName = "Cone";
                    }
                    if (strC != "")
                    {
                        return strP + ">\n" + strC + "</" + typeName + ">\n";
                    }
                    else
                    {
                        return strP + "/>\n";
                    }
                }
                else//保证只包括这些构造组节点的子节点，而排除其属性
                {
                    return strC;
                }
            }
        }
        /// <summary>
        /// 简单单节点的属性获取
        /// </summary>
        /// <param Name="b">对象</param>
        /// <returns>属性表</returns>
        public static string  getX3dAttribute(Object b)
        {
            Type t = b.GetType();
            string strP = "";// "<Attrs object=\"" + typeName + "\">\n";
            //属性
            foreach (PropertyInfo pi in t.GetProperties())
            {
                try
                {
                    object o = pi.GetValue(b, null);
                    if (o != null)
                    {
                        //if (pi.PropertyType == typeof(Tree)) continue;
                        if (pi.PropertyType == typeof(string))      //属于字符串类型，故非复杂类
                        {

                            if (o.ToString().Length != 0)
                            {
                                strP += pi.Name + "|";//"\t<Element Name=\"" + pi.Name + "\" ";
                                strP += o.ToString() + "|" + "null,";//"value=\"" + o.ToString() + "\" />\n";
                            }
                        }
                    }
                }
                catch (Exception )
                {
                }


            }
            return strP.TrimEnd(',') ;// +"</Atrributes>\n";
        }

        public static string[][] getArrayByAttrs(string attr)
        {

            string[] lines = attr.Split(',');
            //保证只有一个属性时也可以
            if (lines.Length == 0) lines = new string[]{attr};
            string[][] array = new string[lines.Length][];
            for (int i = 0; i < lines.Length; i++)
            {
                array[i] = lines[i].Split('|');
            }
            return array;
            
        }

    }
}
